package com.kk.miaosha.controller;

import cn.hutool.http.HttpStatus;
import com.google.common.util.concurrent.RateLimiter;
import com.kk.miaosha.entity.ItemKill;
import com.kk.miaosha.exception.CustomException;
import com.kk.miaosha.exception.R;
import com.kk.miaosha.service.ItemKillService;
import com.kk.miaosha.service.ItemKillSuccessService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author : K k
 * @date : 16:21 2020/9/23
 */
@RestController
@RequestMapping("miaosha")
@Slf4j
@Api(value = "KillController",description = "秒杀系统业务")
public class KillController {

    //订单service
    @Autowired
    private ItemKillSuccessService iksService;
    //创建令牌桶
    private RateLimiter rateLimiter=RateLimiter.create(10);//每秒放行十个请求

    @GetMapping("sale")
    public String sale(Integer id){
       /* log.info("等待的时间"+rateLimiter.acquire());
        System.out.println("-----处理业务-----");*/
       //设置一个等待时间
        if (!rateLimiter.tryAcquire(2, TimeUnit.SECONDS)) {
            System.out.println("当前请求已被限流，直接抛弃，无法调用后续业务");
            return "抢购失败";
        }else {
            System.out.println("业务处理成功");
            return "抢购成功";
        }
    }

    @GetMapping("sale2")
    public String sale2(Integer id){
       /* log.info("等待的时间"+rateLimiter.acquire());
        System.out.println("-----处理业务-----");*/
        //设置一个等待时间
        if (!rateLimiter.tryAcquire(2, TimeUnit.SECONDS)) {
            System.out.println("当前请求已被限流，直接抛弃，无法调用后续业务");
            return "抢购失败";
        }else {
            System.out.println("业务处理成功");
            return "抢购成功";
        }
    }

    //无需登陆的秒杀业务
    @ApiOperation(value = "kill1",notes = "无需登陆的抢购接口")
    @GetMapping("/kill1/{killId}/{userId}")
    public R kill1(@PathVariable("killId") Integer killId,@PathVariable("userId") Integer userId){
        /*synchronized (this) {
            //synchronized保证线程同步，且作用范围必须大于事务
            //悲观锁 不推荐！
            String iksId = iksService.kill(itemId, killId);
            return "秒杀成功，订单号为：" + iksId;
        }*/
        if (rateLimiter.tryAcquire(2, TimeUnit.SECONDS)) {
            //若获取乐观锁，service层实现
            Map<String, Object> map = iksService.kill(killId, userId);
            //System.out.println(res+count++);
            return R.ok("抢购成功！").data(map);
        }else {
            //System.out.println("当前请求已被限流，直接抛弃，无法调用后续业务"+count++);
            return R.error("当前商品抢购过于火爆~ 请重试！");
        }
    }

    //需要登陆的秒杀业务
    @ApiOperation(value = "kill2",notes = "需要登陆的抢购接口")
    @PostMapping("kill2/{killId}/{userId}/{md5}")
    public R kill2(@PathVariable("killId") Integer killId,@PathVariable("userId") Integer userId, @PathVariable("md5")String md5){
        /*synchronized (this) {
            //synchronized保证线程同步，且作用范围必须大于事务
            //悲观锁 不推荐！
            String iksId = iksService.kill(itemId, killId);
            return "秒杀成功，订单号为：" + iksId;
        }*/
        if (rateLimiter.tryAcquire(2, TimeUnit.SECONDS)) {
            //若获取乐观锁，service层实现
            Map<String, Object> map = iksService.kill2(killId, userId, md5);
            //System.out.println(res+count++);
            return R.ok("抢购成功！").data(map);
        }else {
            //System.out.println("当前请求已被限流，直接抛弃，无法调用后续业务"+count++);
            return R.error("当前商品抢购过于火爆~ 请重试！");
        }
    }

    //生成md5值的方法
    @ApiOperation(value = "getMd5",notes = "用户获取抢购前需要携带的加密字符串")
    @GetMapping("md5/{killId}/{userId}")
    public R getMd5(@PathVariable("killId")Integer killId,@PathVariable("userId")Integer userId){
        String md5;
        md5 = iksService.getMd5(killId,userId);
        return R.ok("获取md5成功").data("md5",md5);
    }

}
